package com.jindianjichi.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.gson.Gson;
import com.jindianjichi.auth.common.constant.AuthConstant;
import com.jindianjichi.auth.common.enums.IsDeletedEnum;
import com.jindianjichi.auth.common.enums.StatusEnum;
import com.jindianjichi.auth.domain.BO.AuthUserBO;
import com.jindianjichi.auth.domain.convert.AuthUserBoConvert;
import com.jindianjichi.auth.domain.redis.RedisUtil;
import com.jindianjichi.auth.domain.service.AuthUserDomainService;
import com.jindianjichi.auth.infra.basic.entity.*;
import com.jindianjichi.auth.infra.basic.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;



@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {
    @Autowired
    private AuthUserService authUserService;
    @Autowired
    private AuthRoleService authRoleService;
    @Autowired
    private AuthUserRoleService authUserRoleService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AuthRolePermissionService authRolePermissionService;
    @Autowired
    private AuthPermissionService authPermissionService;
    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private static final String LOGIN_PREFIX = "loginCode";


    private String salt = "chicken";
    @Override
    @Transactional
    public Boolean register(AuthUserBO authUserBO) {
        //校验用户是否存在
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (existUser.size() > 0) {
            return true;
        }
        AuthUser authUser = AuthUserBoConvert.instance.convertToBoAuthUser(authUserBO);
        authUser.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
        authUser.setStatus(StatusEnum.OPEN.getCode());
        if (StringUtils.isNotBlank(authUser.getPassword())) {
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }
        if (StringUtils.isBlank(authUser.getAvatar())) {
            authUser.setAvatar("http://1.94.47.128:9000/user/icon/default.jpg");
        }
        if (StringUtils.isBlank(authUser.getNickName())) {
            authUser.setNickName("鸡翅粉丝");
        }
        int count = authUserService.insert(authUser);
        //建立一个初步的角色的关联
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(AuthConstant.NORMAL_USER);
        //查询角色表获取角色数据
       List<AuthRole>roleList= authRoleService.queryByCondition(authRole);
       if(roleList.size()>0){
            authRole = roleList.get(0);
           AuthUserRole authUserRole = new AuthUserRole();
           authUserRole.setUserId(authUser.getId());
           authUserRole.setRoleId(authRole.getId());
           authUserRole.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
           authUserRoleService.insert(authUserRole);
           List<AuthRole>roles=new LinkedList<>();
           roles.add(authRole);
           String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
           //查询角色对应的权限
           redisUtil.set(roleKey, new Gson().toJson(roles));
           AuthRolePermission authRolePermission = new AuthRolePermission();
           authRolePermission.setRoleId(authRole.getId());
           List<AuthRolePermission> list = authRolePermissionService.queryByPage(authRolePermission);
           //获取所有的roleId
           List<Long> permissionIds = list.stream().map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
           List<AuthPermission>permissionList=new LinkedList<>();
           for (Long permissionId : permissionIds) {
               AuthPermission authPermission = authPermissionService.queryById(permissionId);
               permissionList.add(authPermission);
           }
           String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
           //查询角色对应的权限
           redisUtil.set(permissionKey, new Gson().toJson(permissionList));
       }

        return count>0;
    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBoConvert.instance.convertToBoAuthUser(authUserBO);
     int count=   authUserService.update(authUser);
        return count>0;
    }

    @Override
    public Boolean changeStatus(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBoConvert.instance.convertToBoAuthUser(authUserBO);
        int count=   authUserService.updateByCondition(authUser);
        return count>0;
    }

    @Override
    public Boolean deleteUser(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBoConvert.instance.convertToBoAuthUser(authUserBO);
        authUser.setIsDeleted(IsDeletedEnum.DELETED.getCode());
        int count=   authUserService.updateByCondition(authUser);
        return count>0;
    }

    /**
     * 查询用户信息
     * @param authUserBO
     * @return
     */
    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = new AuthUser();
        authUser.setUserName(authUserBO.getUserName());
        List<AuthUser> authUsers = authUserService.queryByCondition(authUser);
        if (authUsers.size() <= 0) {
            throw new RuntimeException("用户不存在");
        }
        AuthUser user = authUsers.get(0);
        AuthUserBO userBO = AuthUserBoConvert.instance.convertToAuthUser(user);
        return userBO;
    }


    @Override
    public SaTokenInfo doLogin(String validCode) {
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openId = redisUtil.get(loginKey);
        if (StringUtils.isBlank(openId)) {
            return null;
        }
        AuthUserBO authUserBO = new AuthUserBO();
        authUserBO.setUserName(openId);
       this.register(authUserBO);
       StpUtil.login(openId);
       SaTokenInfo saTokenInfo = StpUtil.getTokenInfo();
       log.info("AuthUserDomainServiceImpl.doLogin:{}", saTokenInfo);
       return saTokenInfo;
    }
}
